<!-- 金额组件 -->
<template>
  <view>
    <van-cell-group v-show="!props.hidden">
      <van-field
        :readonly="readonly"
        clickable
        clearable
        v-model="_value"
        type="number"
        :name="props.formItem?.id"
        :label="props.formItem?.title"
        :placeholder="props.placeholder"
        :required="props.required"
        :rules="rules"
        :input-align="FieldInputAlign.DEFAULT"
      />
      <van-field
        v-show="showChinese"
        v-model="chinese"
        label="大写"
        readonly
        rows="1"
        autosize
        type="textarea"
        :input-align="FieldInputAlign.DEFAULT"
      />
    </van-cell-group>
  </view>
</template>

<script setup lang="ts">
  import { computed, watch, WritableComputedRef } from 'vue';
  import { isEmpty } from '@/utils/is';
  import { evalFormual } from '@/utils/evalFormual';
  import { FieldInputAlign } from '@/enums/formEnum';
  const emits = defineEmits(['update:value', 'labelShow']);
  const props = defineProps({
    value: {
      type: String,
      default: '',
    },
    required: {
      type: Boolean,
      default: false,
    },
    readonly: {
      type: Boolean,
      default: false,
    },
    //隐藏组件的公共属性
    formula: {
      type: Object,
      default: () => {
        return {
          showFormula: '', //回显用，因为包含表单字段的时候会出现表单名称
          calcFormula: '', //解析用，表单名称对应为formData.fieldxxxx
        };
      },
    },
    formItem: {
      type: Object,
      default: () => {},
    },
    formData: {
      type: Object,
      default: () => {
        return {};
      },
    },
    rule: {
      type: Object,
      default: () => null,
    },
    placeholder: {
      type: String,
      default: '请输入金额',
    },
    showChinese: {
      type: Boolean,
      default: true,
    },
    precision: {
      type: Number,
      default: 0,
    },
    hidden: {
      type: Boolean,
      default: false,
    },
  });
  /** 计算属性：_value */
  const _value = computed({
    get() {
      return isEmpty(props.value) ? null : parseNumber(props.value);
    },
    set(val) {
      emits('update:value', val);
    },
  });
  const parseNumber = (val: string) => {
    return props.precision > 0
      ? parseFloat(parseFloat(val).toFixed(props.precision))
      : parseInt(val);
  };
  const chinese = computed(() => convertCurrency(_value.value));

  //对输入的值的小数点进行处理，判断当前保留的小数点位数
  /*const handleInputValue = debounce((value: number) => {
  if (props.precision > 0) {
    if (value.toString().indexOf('.') > 0) {
      _value.value = value.toFixed(props.precision);
    }
  }
}, 300);
//监听输入的值，通过防抖函数处理
const handleInput = () => {
  //    handleInputValue(_value.value);
};*/

  /** 校验规则 */
  const rules = computed(() => {
    if (isEmpty(props.rule)) {
      return [];
    } else {
      return props.rule;
    }
  });

  const doFormula = () => {
    let hidden = evalFormual(props.formula.calcFormula, props.formData);
    //如果隐藏，同时也隐藏label,通知父组件去隐藏，因为label不在当前界面
    //调用父组件FormDesignRender 的方法：
    emits('labelShow', props.formItem, hidden);
  };

  watch(
    () => props.formData,
    () => {
      doFormula();
    },
    { immediate: true, deep: true },
  );

  const convertCurrency = (money: any) => {
    // 汉字的数字
    const cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
    // 基本单位
    const cnIntRadice = ['', '拾', '佰', '仟'];
    // 对应整数部分扩展单位
    const cnIntUnits = ['', '万', '亿', '兆'];
    // 对应小数部分单位
    const cnDecUnits = ['角', '分', '毫', '厘'];
    // 整数金额时后面跟的字符
    const cnInteger = '整';
    // 整型完以后的单位
    const cnIntLast = '元';
    // 最大处理的数字
    const maxNum = 999999999999999n;
    // 金额整数部分
    let integerNum;
    // 金额小数部分
    let decimalNum;
    // 输出的中文金额字符串
    let chineseStr = '';
    // 分离金额后用的数组，预定义
    let parts;
    if (money === '') {
      return '';
    }
    money = parseFloat(money);
    if (money >= maxNum) {
      // 超出最大处理数字
      return '';
    }
    if (isNaN(money)) {
      return '';
    }
    if (money === 0) {
      chineseStr = cnNums[0] + cnIntLast + cnInteger;
      return chineseStr;
    }
    // 转换为字符串
    money = money.toString();
    if (money.indexOf('.') === -1) {
      integerNum = money;
      decimalNum = '';
    } else {
      parts = money.split('.');
      integerNum = parts[0];
      decimalNum = parts[1].substr(0, 4);
    }
    // 获取整型部分转换
    if (parseInt(integerNum, 10) > 0) {
      let zeroCount = 0;
      let IntLen = integerNum.length;
      for (let i = 0; i < IntLen; i++) {
        let n = integerNum.substr(i, 1);
        let p = IntLen - i - 1;
        let q = p / 4;
        let m = p % 4;
        if (n == '0') {
          zeroCount++;
        } else {
          if (zeroCount > 0) {
            chineseStr += cnNums[0];
          }
          // 归零
          zeroCount = 0;
          chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
        }
        if (m == 0 && zeroCount < 4) {
          chineseStr += cnIntUnits[q];
        }
      }
      chineseStr += cnIntLast;
    }
    // 小数部分
    if (decimalNum !== '') {
      let decLen = decimalNum.length;
      for (let i = 0; i < decLen; i++) {
        let n = decimalNum.substr(i, 1);
        if (n !== '0') {
          chineseStr += cnNums[Number(n)] + cnDecUnits[i];
        }
      }
    }
    if (chineseStr === '') {
      chineseStr += cnNums[0] + cnIntLast + cnInteger;
    } else if (decimalNum === '') {
      chineseStr += cnInteger;
    }
    return chineseStr;
  };
</script>

<style scoped></style>
